package com.ruoyi.count.controller;

import com.alibaba.fastjson2.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.ruoyi.classscoreonmonth.domain.Classscoreonmonth;
import com.ruoyi.classscoreonmonth.service.IClassscoreonmonthService;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.count.domain.*;
import com.ruoyi.count.service.CountService;
import com.ruoyi.count.service.IStudentstandardscoresService;
import com.ruoyi.count.until.StatisticsCalculator;
import com.ruoyi.education.domain.Indicator;
import com.ruoyi.education.domain.Score;
import com.ruoyi.education.service.IIndicatorService;
import com.ruoyi.education.service.IScoreService;
import com.ruoyi.students.domain.Students;
import com.ruoyi.students.mapper.StudentsMapper;
import com.ruoyi.students.service.IStudentsService;
import com.ruoyi.system.service.ISysDeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 进行分数计算的controller
 * @author 尹欣雨
 * @verdion 520
 * 13:23
 */
@Anonymous
@RestController
@RequestMapping("/count/count")
public class countContorller {

    @Autowired
    private IScoreService scoreService;
    @Autowired
    private IStudentsService studentsService;
    @Autowired
    private IIndicatorService indicatorService;
    @Autowired
    private CountService countService;
    @Autowired
    private IStudentstandardscoresService studentstandardscoresService;
    @Autowired
    private ISysDeptService deptService;
    @Autowired
    private IClassscoreonmonthService classscoreonmonthService;
    @Autowired
    private StudentsMapper studentsMapper;
    /**
     * 获取特定学生特定月份的成绩
     */
    @Anonymous
    @ResponseBody
    @GetMapping(value = "/{studentId}/{evaluationDate}")
    public List<Score> getGradeScore(@PathVariable String studentId, @PathVariable String evaluationDate){
        // 根据给定学生的学号（studentId）查找该学生所在年级的所有学生的得分记录
        List<Score> list = studentsService.selectStudentsListBystudentId(studentId,evaluationDate);
        return list;
    }



    /**
     * 获取该年级已经生成过成绩的月份
     * 以防止重复生成
     */
    @Anonymous
    @ResponseBody
    @GetMapping("/getCalculationTime/{grade}/{schoolId}")
    public String getCalculationTime(@PathVariable("grade") String grade, @PathVariable("schoolId") String schoolId){
        return studentstandardscoresService.getCalculationTime(grade,schoolId);
    }



    /**
     * A学校B年级管理员点击生成,拿取该年级所有学生的score
     * 特定学校 , 年级 , 月份
     * 调用函数计算该月份的学生成绩
     */
    @Anonymous
    @ResponseBody
    @GetMapping(value = "/AllStudentScaore/{grade}/{schoolId}/{month}")
    public List<StudentStatistics> StudnetScoreAllBymanage(@PathVariable("grade") String grade, @PathVariable("schoolId") String schoolId, @PathVariable("month") String month) throws JsonProcessingException, ParseException {
        System.out.println("grade:"+grade);
        System.out.println("schoolId:"+schoolId);
        // 拿到成绩记录表中的原始只有三级指标的数据
        List<StudentScore> studentScores = countService.getStudentScores(grade,schoolId,month);
        // 进行计算
        return insertScore(studentScores,grade,schoolId,month);
    }


    /**
     * 统一计算所有学生的标准分,并且把标准分&Z分数插入数据库
     */

    public List<StudentStatistics>  insertScore(List<StudentScore> studentScores,String grade,String schoolId,String month) throws JsonProcessingException, ParseException {
        // 获取指标权重
        List<Indicator> indicatorInfo = getIndicatorWeight(grade, schoolId);
        System.out.println(indicatorInfo);
        Map<String, Long> weightsMap = new HashMap<>();
        for (Indicator indicator : indicatorInfo) {
            String treeCode = indicator.getTreeCode();
            Long weight = indicator.getWeight();
            if (treeCode != null) {
                weightsMap.put(treeCode, weight);
            }
        }
        // 学生分数记录 studentScores  权重集合 weightsMap
        // 利用until工具类的StatisticsCalculator函数进行计算各指标的Z分数和标准分数
        List<StudentStatistics> studentStatistics = StatisticsCalculator.calculateZScores(studentScores,weightsMap);
        // 将返回的数据插入数据库
        Studentstandardscores studentstandardscores = new Studentstandardscores();
        for (StudentStatistics studentStatistic : studentStatistics) {
            studentstandardscores.setStudentId(studentStatistic.getStudentId());

            // 获取学生班级
            Students students = studentsMapper.selectStudentsByStudentId(studentStatistic.getStudentId());
            studentstandardscores.setClasss(students.getStudentclass());

            studentstandardscores.setGrade(grade);
            studentstandardscores.setSchool(schoolId);
            studentstandardscores.setZscores(studentStatistic.getStatisticsZcoreJson());
            studentstandardscores.setStrandScore(studentStatistic.getStatisticsStrandJson());

            // 进行日期格式化转换
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyy-MM");
            studentstandardscores.setCalculationtime(inputFormat.parse(month));

            studentstandardscoresService.insertStudentstandardscores(studentstandardscores);
        }
        genateClassScore(grade,schoolId,month);
        return studentStatistics;
    }

    /**
     * 插入学生信息后 生成班级成绩信息
     */
    public void genateClassScore(String grade, String schoolId, String month) throws ParseException {
        Studentstandardscores studentstandardscores = new Studentstandardscores();
        studentstandardscores.setGrade(grade);
        studentstandardscores.setSchool(schoolId);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
        studentstandardscores.setCalculationtime(sdf.parse(month));
        List<Studentstandardscores> studentstandardscoresList = studentstandardscoresService.selectStudentstandardscoresList(studentstandardscores);
        // 用于按班级分组学生成绩的 Map
        Map<String, List<ClassScoretemp>> classScoreMap = new HashMap<>();
        for(Studentstandardscores element : studentstandardscoresList){
            String studentId = element.getStudentId();
            // 查找当前同学的班级
            String classId = studentsService.selectStudentClassName(studentId);
            String Zscore = element.getZscores();
            String strandScore = element.getStrandScore();
            ClassScoretemp classScoretemp = new ClassScoretemp();
            classScoretemp.setZscore(Zscore);
            classScoretemp.setStrandScore(strandScore);
            // 将学生成绩添加到对应班级的成绩列表中
            classScoreMap.computeIfAbsent(classId, k -> new ArrayList<>()).add(classScoretemp);
        }

        // 存储结束 , 那么开始遍历进行计算每个班级的成绩
        classScoreMap.forEach((classId, classScores) -> {
            ClassScoretemp list = StatisticsCalculator.generateClassScore(classScores);
            // 创建班级成绩对象
            Classscoreonmonth classscoreonmonth = new Classscoreonmonth();
            classscoreonmonth.setClassid(classId);
            classscoreonmonth.setGrade(grade);
            classscoreonmonth.setSchool(schoolId);
            classscoreonmonth.setMonth(month);
            classscoreonmonth.setCreateTime(new Date());
            classscoreonmonth.setStrandScore(list.getStrandScore());
            classscoreonmonth.setTransformScore(list.getTransformScore());
            classscoreonmonth.setZscore(list.getZscore());
            classscoreonmonthService.insertClassscoreonmonth(classscoreonmonth);
        });
    }


    /**
     * 根据学校 , 年级
     * 查询这个年级所用指标的权重信息
     */
    @Anonymous
    @ResponseBody
    public List<Indicator> getIndicatorWeight(String grade,String schoolId){
        Indicator indicator = new Indicator();
        indicator.setGradeID(grade);
        indicator.setSchoolID(schoolId);
        return indicatorService.selectIndicatorList(indicator);
    }

    /**
     * 查询部门信息
     */
    @PreAuthorize("@ss.hasPermi('genetate')")
    @GetMapping(value = "/deptlist/{deptid}")
    public SysDept list(@PathVariable("deptid") long deptId)
    {
        SysDept list = deptService.selectDeptById(deptId);
        return list;
    }
}